/**
 * @author Mahesh
 */
var MICRO_DURATION_SECONDS = 30;
var MICRO_FREQUENCY_SECONDS = 600;
var MICRO_NOTIFICATION_AUDIO_FILE = "../Resources/alert.wav";

var MACRO_DURATION_SECONDS = 600;
var MACRO_FREQUENCY_SECONDS = 3600;
var MACRO_NOTIFICATION_AUDIO_FILE = "../Resources/alert.wav";

function Synchronizer() {
	// Properties
	var self = this;
	var notification = new Notification(this); // Handle to the notification displayed

	var microBreak = new Break("micro", MICRO_DURATION_SECONDS,
			MICRO_FREQUENCY_SECONDS, MICRO_NOTIFICATION_AUDIO_FILE);
	var macroBreak = new Break("macro", MACRO_DURATION_SECONDS,
			MACRO_FREQUENCY_SECONDS, MACRO_NOTIFICATION_AUDIO_FILE);

	var showNotificationInterval;
	var microMacroRatio;
	
	// Persist the default values in local storage
	microBreak.persistValues();
	macroBreak.persistValues();

	// Load any existing values from the local storage
	microBreak.loadValues();
	macroBreak.loadValues();
	
	// Calculate the ratio of micro to macro breaks set to be shown
	resetMicroMacroRatio();

	// Public Methods
	this.getMicroBreak = function() {
		return microBreak;
	};
	
	this.getMacroBreak = function() {
		return macroBreak;
	};
	
	this.getNotification = function() {
		return notification;
	};

	this.getBreakObjects = function() {
		return new Array(microBreak, macroBreak);
	};

	this.getNextBreakTime = function() {
		return this.getNextBreak().getNextBreakTime();
	};
	
	this.getNextBreakTimeIncludingDuration = function() {
		return this.getNextBreak().getNextBreakTimeIncludingDuration();
	};

	// Determine if the next break is micro or macro and return the
	// corresponding object
	this.getNextBreak = function() {
		if(microMacroRatio > 0) return microBreak;
		else return macroBreak;
	};

	this.pauseBreak = function() {
		// Change the button to handle resume request
		// To learn why the events handler is the way it is, visit
		// http://www.digital-web.com/articles/scope_in_javascript/
		$('#pauseResumeBreak')[0].removeEventListener('click',
				this.pauseBreak.bind(this), false);
		$('#pauseResumeBreak')[0].addEventListener('click',
				this.resumeBreak.bind(this), false);

		$('#pauseResumeBreak')[0].innerHTML = "Resume Breaks";
		setDisplayTime("No Breaks Scheduled");

		// Remove the event listeners on the notification
		notification.clear();

		clearIntervals();
	};

	this.resumeBreak = function() {
		// Change the button to handle pause request
		$('#pauseResumeBreak')[0].addEventListener('click',
				this.pauseBreak.bind(this), false);
		$('#pauseResumeBreak')[0].removeEventListener('click',
				this.resumeBreak.bind(this), false);

		$('#pauseResumeBreak')[0].innerHTML = "Pause Breaks";

		this.restartBreak();
	};

	this.displayNotification = function() {
		if (!notification.isNotificationEnabled())
			alert("Please enable notifications");
		clearIntervals();

		var nextBreakObject = self.getNextBreak();
		nextBreakObject.setPrevBreakTime(new Date());
		
		setDisplayTime("Break Running");
		notification.display(nextBreakObject); 
		
		microMacroRatio--;
		if(microMacroRatio < 0) resetMicroMacroRatio();
	};

	this.endBreak = function() {
		var nextBreakObject = self.getNextBreak();
		if (nextBreakObject.isSoundEnabled()) {
			playSound(nextBreakObject.getNotificationAudioFile());
		}
		notification.close();
	};

	this.restartBreak = function() {
		clearIntervals();
		this.startBreak();
	};

	this.startBreak = function() { 
		// Duration between the breaks should always be the microBreak frequency, so microBreak is hardcoded here
		// If this is not done, the lag between micro and macro break will be equal to the macroBreak frequency 
		// which is a lot of time, in most cases
		showNotificationInterval = setInterval(self.displayNotification, microBreak.getFrequency() * 1000);
		setDisplayTime(microBreak.getNextBreakTime().toLocaleTimeString());
	};

	// To be called when the settings are changed in settings window
	this.reloadSettings = function(){
		microBreak.loadValues();
		macroBreak.loadValues();
	};
	
	// Private Methods
	function clearIntervals() {
		clearInterval(showNotificationInterval);
	}
	
	function resetMicroMacroRatio() {
		microMacroRatio = Math.round(MACRO_FREQUENCY_SECONDS / MICRO_FREQUENCY_SECONDS);
	}
	
	function setDisplayTime(time) {
		$('#nextBreakTimeDisplay')[0].innerHTML = '';
		$('#nextBreakTimeDisplay').countdown({
		      image: '../Resources/digits.png',
		      startTime: time,
		      format: 'hh:mm:ss',
		      doNotCountDown: true
		    });
	}
}

var synchronizer;
window.addEventListener('load', homePageOnloadFunction, false);
function homePageOnloadFunction() {
	synchronizer = new Synchronizer();
	synchronizer.startBreak();

	// Event handlers
	$('#pauseResumeBreak')[0].addEventListener('click', synchronizer.pauseBreak.bind(synchronizer), false); 
	
	if (window.webkitNotifications.checkPermission() != 0) {
		$('#desktopNotificationRequestBanner')[0].style.visibility = "visible";
		$('#enableNotifications')[0].addEventListener('click', synchronizer.getNotification().requestPermission, false);
	}
	
	// To be deleted in final release, once the settings logic is complete
	// localStorage.clear();
}
